<template>
  <template v-if="props.showFileList">
    <a-upload
      ref="uploadRef"
      :id="uploadUUID"
      :headers="uploadHeaders"
      :action="uploadAction"
      :custom-request="customRequest"
      :data="uploadData"
      :show-file-list="props.showFileList"
      :name="props.name"
      :accept="props.accept"
      :limit="props.limit"
      :multiple="true"
      :list-type="props.listType"
      :image-preview="props.imagePreview"
      :file-list="fileData"
      :custom-icon="uploadCustomIcon()"
      :on-before-upload="uploadBefore"
      @success="uploadSuccess"
      @error="uploadError"
      @change="uploadChange"
      @exceed-limit="uploadLimit"
    >
<!--      <template #extra-button="{ fileItem }">
        <template v-if="props.listType === 'picture-card'">
          <span>
            <icon-arrow-left @click="moveFile(fileItem, 'left')"/>
          </span>
          <span>
            <icon-arrow-right @click="moveFile(fileItem, 'right')"/>
          </span>
        </template>
        <template v-else>
          <span>
            <icon-arrow-up @click="moveFile(fileItem, 'left')"/>
          </span>
          <span>
            <icon-arrow-down @click="moveFile(fileItem, 'right')"/>
          </span>
        </template>
      </template>-->
    </a-upload>
  </template>
  <template v-else-if="isButton">
    <a-upload
      ref="uploadRef"
      :id="uploadUUID"
      :headers="uploadHeaders"
      :action="uploadAction"
      :custom-request="customRequest"
      :data="uploadData"
      :name="props.name"
      :accept="props.accept"
      @before-upload="uploadBefore"
      @success="uploadSuccess"
      @error="uploadError"
      @change="uploadChange"
    >
    </a-upload>
  </template>
  <template v-else>
    <a-upload
      ref="uploadRef"
      :id="uploadUUID"
      :headers="uploadHeaders"
      :action="uploadAction"
      :custom-request="customRequest"
      :data="uploadData"
      :show-file-list="props.showFileList"
      :name="props.name"
      :accept="props.accept"
      :file-list="singleFileData ? [singleFileData] : []"
      @before-upload="uploadBefore"
      @success="uploadSuccess"
      @error="uploadError"
      @change="uploadChange"
    >
      <template #upload-button>
        <div :class="`arco-upload-list-item${singleFileData && singleFileData.status === 'error' ? ' arco-upload-list-item-error' : ''}`">
          <div
            v-if="singleFileData && singleFileData.url"
            class="arco-upload-list-picture custom-upload-avatar"
            @click.stop
          >
            <img :src="singleFileData.url" />
            <div class="arco-upload-list-picture-mask">
              <a-space>
                <icon-eye @click="imagePreviewVisible = true" />
                <icon-edit @click="againUpload" />
                <icon-delete @click="removeFile" />
              </a-space>
            </div>
            <a-progress
              v-if="singleFileData.status === 'uploading' && singleFileData.percent < 100"
              :percent="singleFileData.percent"
              type="circle"
              size="mini"
              :style="{
                position: 'absolute',
                left: '50%',
                top: '50%',
                transform: 'translateX(-50%) translateY(-50%)',
              }"
            />
          </div>
          <div v-else class="arco-upload-picture-card">
            <div class="arco-upload-picture-card-text">
              <IconPlus />
              <div v-if="props.uploadText" style="margin-top: 10px; font-weight: 600">{{ props.uploadText }}</div>
            </div>
          </div>
        </div>
      </template>
    </a-upload>
  </template>

  <a-image-preview
    v-model:visible="imagePreviewVisible"
    :src="singleFileData.url"
  />
</template>

<script setup>
  import { ref, computed, onMounted } from 'vue';
  import { Message } from '@arco-design/web-vue';

  import { useAdminStore } from '@/store';
  import { uploadURL, apiUpload } from '@/api/common';

  const props = defineProps({
    // 多文件
    fileList: {
      type: Array,
      default() {
        return [];
      },
    },
    // 单文件
    singleFile: {
      type: Object,
      default() {
        return {
          url: '',
          path: '',
          field: '',
        };
      }
    },
    // 是否显示已上传文件列表
    showFileList: {
      type: Boolean,
      default: true
    },
    // 上传的文件名
    name: {
      type: String,
      default: 'file',
    },
    // 图片列表类型
    listType: {
      type: String,
      default() {
        return 'picture-card';
      },
    },
    // 是否使用 ImagePreview 组件进行预览
    imagePreview: {
      type: Boolean,
      default: true
    },
    // 多文件上传数量
    limit: {
      type: Number,
      default: 9,
    },
    // 上传图片大小最大限制(单位：M)
    imageMaxSize: {
      type: Number,
      // default: 500, // 单位：KB
      default: 2,
    },
    // 上传文件大小最大限制(单位：M)
    maxSize: {
      type: Number,
      default: 20,
    },
    // 上传文件类型
    accept: {
      type: String,
      default: 'image/jpeg, image/png, image/gif, text/plain, text/csv, application/vnd.ms-excel, application/msword, application/pdf, application/vnd.ms-powerpoint, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, audio/mp4, video/mp4, aplication/zip', // audio/*, video/*, image/*
    },
    uploadText: {
      type: String,
      default: 'Upload',
    },
    // 是否按钮上传
    isButton: {
      type: Boolean,
      default: false,
    },
    // 按钮上传对应按钮名称
    buttonText: {
      type: String,
      default: '选择文件',
    },
    // 字段，区分同时调用多个组件
    field: {
      type: [Number, String],
      default: 0,
    },
    // 是否只返回base64 格式，不上传到服务器
    isBase64: {
      type: Boolean,
      default: false,
    },
    // 是否剪裁
    cropper: {
      type: Boolean,
      default: true,
    },
  });

  const emit = defineEmits(['uploadCallback']);

  const adminStore = useAdminStore();
  const uploadHeaders = {
    token: adminStore.getToken(),
  };
  const uploadAction = uploadURL();
  // 上传请求附加的数据
  const uploadData = ref({
    // folder: 'default',
    // place: 'local',
    multi: props.showFileList,
    total_count: props.limit,
    count: 0,
  });
  const uploadRef = ref();
  const allFileDatas = ref([]);
  const uploadUUID = `upload-${(Math.random() * 1000).toFixed(0)}`;
  const imagePreviewVisible = ref(false);

  const fileData = computed({
    get() {
      return props.fileList;
    },
    set(val) {
      // emit('uploadCallback', val);
    },
  });
  const singleFileData = computed({
    get() {
      return props.singleFile;
    },
    set(val) {
      // emit('uploadCallback', val);
    },
  });

  // 上传回调
  const uploadCBK = () => {
    if (props.showFileList) {
      emit('uploadCallback', allFileDatas.value);
    } else {
      emit('uploadCallback', allFileDatas.value[0]);
    }
  };
  // 上传自定义图标
  const uploadCustomIcon = () => {
    return {
      fileName: (file) => {
        return `文件名： ${file.name}`;
      },
    };
  };
  const afterSuccess = (response) => {
    const fileInfo = {
      uid: new Date().getTime(),
      name: response.data.name,
      url: response.data.src,
      size: response.data.size,
      date: response.data.date,
      filepath: response.data.filepath,
      creatorid: adminStore.id,
      field: props.field,
    };
    if (props.showFileList) {
      if (!allFileDatas.value) {
        allFileDatas.value = fileData.value;
      }
      allFileDatas.value.push(fileInfo);
    } else {
      fileInfo.field = singleFileData.value.field;
      allFileDatas.value = [fileInfo];
    }
    uploadCBK();
  };
  const uploadBefore = (file) => {
    let fileMaxSize = props.maxSize;
    if (['image/jpg', 'image/jpeg', 'image/png', 'image/gif'].includes(file.type)) {
      fileMaxSize = props.imageMaxSize;
    }
    // return new Promise((resolve, reject) => {
    //   if (file.size / 1024 / 1024 > 20) {
    //     // reject(new Error(`文件大小请控制在 ${fileMaxSize}M 以内`));
    //     Message.info(`文件大小请控制在 ${fileMaxSize}M 以内`);
    //     resolve(false);
    //   }
    //   resolve(true);
    // });
    if (file.size / 1024 / 1024 > 20) {
      Message.info(`文件大小请控制在 ${fileMaxSize}M 以内`);
      return false;
    }
    return true;
  };
  const customRequest = (options) => {
    const controller = new AbortController();
    (async function requestWrap() {
      const {
        onProgress,
        onError,
        onSuccess,
        fileItem,
        name,
      } = options;
      onProgress(20);
      // if (props.cropper) {
      //   cropperImg.value.url = fileItem.url;
      //   openCropper();
      // }
      if (!props.isBase64) {
        const formData = new FormData();
        formData.append(name, fileItem.file);
        const onUploadProgress = (event) => {
          let percent;
          if (event.total > 0) {
            percent = (event.loaded / event.total) * 100;
          }
          onProgress(parseInt(String(percent), 10), event);
        };
        await apiUpload(formData, {
          controller,
          onUploadProgress,
        }).then(res => {
          if (res.status === 1) {
            afterSuccess(res);
            onSuccess(res);
          }
        }).catch(error => {
          onError(error);
        });
      } else {
        const reader = new FileReader();
        reader.onload = function(event) {
          const base64Data = event.target.result;
          const response = {
            data: {
              name: fileItem.file.name,
              src: base64Data,
              size: fileItem.file.size,
              date: '',
              filepath: base64Data,
            },
          };
          afterSuccess(response);
        };
        reader.readAsDataURL(fileItem.file);
      }
    })();
    return {
      abort() {
        controller.abort();
      },
    };
  };
  // 放弃【使用 custom-request 进行上传】
  const uploadSuccess = (fileItem) => {
    const { response } = fileItem;
    if (response.status === 1) {
      // afterSuccess(response); // 多文件上传只会执行一次
    } else {
      Message.error({
        content: response.msg || 'Error',
      });
    }
  };
  const uploadError = (fileItem) => {
    console.log(fileItem);
  };
  const uploadChange = (fileList, fileItem) => {
    if (props.showFileList) {
      const { response } = fileItem;
      if (response) {
        // 上传
        if (response.status === 1) {
          allFileDatas.value = fileData.value;
        }
      } else {
        // 删除操作
        allFileDatas.value = fileData.value;
        // const fileInfo = {
        //   uid: fileItem.uid,
        //   name: fileItem.name,
        //   url: fileItem.url,
        //   size: fileItem.size,
        //   date: fileItem.date,
        //   creatorid: fileItem.creatorid,
        // };
        allFileDatas.value.forEach((item, index) => {
          if (item.uid === fileItem.uid) {
            allFileDatas.value.splice(index, 1);
          }
        });
        uploadCBK();
      }
    }
  };
  const uploadLimit = (fileList, files) => {
    Message.warning(`最多上传 ${props.limit} 个文件`);
  };
  const againUpload = () => {
    const dom = document.querySelector(`#${uploadUUID} input`);
    if (dom) {
      dom.addEventListener('click', function (e) {
        // console.log('upload');
      }, false);
      dom.dispatchEvent(new MouseEvent('click'));
    }
  };
  const removeFile = () => {
    allFileDatas.value = [
      {
        uid: new Date().getTime(),
        name: '',
        url: '',
        size: 0,
        date: '',
        filepath: '',
        creatorid: adminStore.id,
        field: props.field,
      }
    ];
    uploadCBK();
  };
  // 当 list-type="picture-card" 时，fileItem 为 Undefined
  const moveFile = (fileItem, type) => {
    if (fileItem) {
      // if (!allFileDatas.value || allFileDatas.value.length <= 0) {
      //   allFileDatas.value = fileData.value;
      // }
      // const newFileDatas = JSON.parse(JSON.stringify(allFileDatas.value));
      // newFileDatas.forEach((item, index) => {
      //   if (item.uid === fileItem.uid) {
      //     if (type === 'left') {
      //       // 将 index 和 index-1 位置的元素互换
      //       if (newFileDatas[index - 1]) {
      //         newFileDatas[index - 1] = newFileDatas.splice(index, 1, newFileDatas[index - 1])[0];
      //       }
      //     } else {
      //       // 将 index 和 index+1 位置的元素互换
      //       if (newFileDatas[index + 1]) {
      //         newFileDatas[index + 1] = newFileDatas.splice(index, 1, newFileDatas[index + 1])[0];
      //       }
      //     }
      //   }
      // });
      // // 有问题
      // allFileDatas.value = newFileDatas;
      // props.fileList = allFileDatas.value;
      // uploadCBK();
    }
  };

  onMounted(async () => {
    // console.log(props.singleFile); // 无效
    // console.log(singleFileData);
    console.log(props.fileList);
  });
</script>

<style lang="less">
  .arco-upload-list-item {
    margin-top: 0;
  }
</style>
